/**
*****************************************************************************************
*     Copyright(c) 2017, Realtek Semiconductor Corporation. All rights reserved.
*****************************************************************************************
   * @file      main.c
   * @brief     Source file for BLE peripheral project, mainly used for initialize modules
   * @author    jane
   * @date      2017-06-12
   * @version   v1.0
   **************************************************************************************
   * @attention
   * <h2><center>&copy; COPYRIGHT 2017 Realtek Semiconductor Corporation</center></h2>
   **************************************************************************************
  */

/*============================================================================*
 *                              Header Files
 *============================================================================*/
#include <stdlib.h>
#include <os_sched.h>
#include <string.h>
#include <trace.h>
#include <gap.h>
#include <gap_adv.h>
#include <gap_bond_le.h>
#include <profile_server.h>
#include <gap_msg.h>
#include <simple_ble_service.h>
#include <bas.h>
#include <app_task.h>
#include <peripheral_app.h>
#include "board.h"
#include "app_main.h"
#include "mi_config.h"

#if F_BT_DLPS_EN
#include <dlps.h>
#include <rtl876x_io_dlps.h>
#endif

#include "rtl876x_gpio.h"
#include "rtl876x_nvic.h"
#include "rtl876x_pinmux.h"
#include "rtl876x_rcc.h"
#include "rtl876x_rtc.h"

#include "rtk_uart.h"
#include "mible_api.h"
#include "mible_log.h"
#include "mible_trace.h"


#include "gwin_board.h"
#include "gwin_global_data.h"
#include "gwin_main_task.h"
#include "gwin_protocol_task.h"


#include <time.h>

extern void time_init(struct tm * time_ptr);

/** @defgroup  PERIPH_DEMO_MAIN Peripheral Main
    * @brief Main file to initialize hardware and BT stack and start task scheduling
    * @{
    */

/*============================================================================*
 *                              Functions
 *============================================================================*/
/**
  * @brief  Initialize peripheral and gap bond manager related parameters
  * @return void
  */
static void app_le_gap_init(void)
{
    /* Device name and device appearance */
    uint8_t  device_name[] = "secure demo";
    uint16_t appearance = GAP_GATT_APPEARANCE_UNKNOWN;
    uint8_t  slave_init_mtu_req = false;

    /* Set device name and device appearance */
    le_set_gap_param(GAP_PARAM_DEVICE_NAME, sizeof(device_name), device_name);
    le_set_gap_param(GAP_PARAM_APPEARANCE, sizeof(appearance), &appearance);
    le_set_gap_param(GAP_PARAM_SLAVE_INIT_GATT_MTU_REQ, sizeof(slave_init_mtu_req),
                     &slave_init_mtu_req);

    /* register gap message callback */
    le_register_app_cb(app_gap_callback);
}

/**
 * @brief  Add GATT services and register callbacks
 * @return void
 */
static void app_le_profile_init(void)
{
    server_init(3);
    server_register_app_cb(app_profile_callback);

    /** set ble stack log level, disable nonsignificant log */
    log_module_bitmap_trace_set(0xFFFFFFFFFFFFFFFF, LEVEL_TRACE, 0);
    log_module_bitmap_trace_set(0xFFFFFFFFFFFFFFFF, LEVEL_INFO, 0);
    log_module_trace_set(MODULE_LOWERSTACK, LEVEL_ERROR, 0);
    log_module_trace_set(MODULE_SNOOP, LEVEL_ERROR, 0);

}

/**
 * @brief    Contains the initialization of pinmux settings and pad settings
 * @note     All the pinmux settings and pad settings shall be initiated in this function,
 *           but if legacy driver is used, the initialization of pinmux setting and pad setting
 *           should be peformed with the IO initializing.
 * @return   void
 */
extern void user_record_init(void);
void board_init(void)
{
    /* Initialize rtc peripheral. */
//    MI_LOG_INFO("rtc init!!!!!!!!");
//    RTC_DeInit();
//    RTC_SetPrescaler(31);//f=1000Hz
//    RTC_RunCmd(ENABLE);
    time_init(NULL);
    //time_t utc_time = time(NULL);
    //MI_LOG_INFO("rtc init: %s\r\n", ctime(&utc_time));


    user_record_init();
    gwin_custom_record_load();      // 加载系统参数
    gwin_board_init();              // 板载初始化
}

/**
 * @brief    System_Handler
 * @note     system handle to judge which pin is wake source
 * @return   void
 */
void System_Handler(void)
{
    MI_LOG_INFO("SysISR\n");
    NVIC_DisableIRQ(System_IRQn);

    if (System_WakeUpInterruptValue(BUTTON_0))
    {
//        GPIO_BUTTON_Handler();
    }

    gwin_low_pwr_interrupt_handler();

    // MUST clear debounce bit here. (NONE KNOWS WHAT CODE IS, WTF?)
    btaon_fast_write_safe(0x2b, (btaon_fast_read_safe(0x2b) | BIT7));
#if MI_MCU_CMD_ENABLE
    rtk_mcu_wakeup();
#endif
    NVIC_ClearPendingIRQ(System_IRQn);
}

/**
 * @brief    Contains the initialization of peripherals
 * @note     Both new architecture driver and legacy driver initialization method can be used
 * @return   void
 */
static void driver_init(void)
{
/*
    Pad_Config(P4_1, PAD_PINMUX_MODE, PAD_IS_PWRON, PAD_PULL_NONE, PAD_OUT_DISABLE, PAD_OUT_LOW);
    Pad_Config(P0_0, PAD_PINMUX_MODE, PAD_IS_PWRON, PAD_PULL_DOWN, PAD_OUT_DISABLE, PAD_OUT_LOW);
    Pad_Config(P0_1, PAD_PINMUX_MODE, PAD_IS_PWRON, PAD_PULL_DOWN, PAD_OUT_DISABLE, PAD_OUT_LOW);
    Pad_Config(P0_2, PAD_PINMUX_MODE, PAD_IS_PWRON, PAD_PULL_DOWN, PAD_OUT_DISABLE, PAD_OUT_LOW);

    Pad_Config(P4_2, PAD_PINMUX_MODE, PAD_IS_PWRON, PAD_PULL_UP, PAD_OUT_DISABLE, PAD_OUT_LOW);
*/
}

#if F_BT_DLPS_EN
/**
 * @brief this function will be called before enter DLPS
 *
 *  set PAD and wakeup pin config for enterring DLPS
 *
 * @param none
 * @return none
 * @retval void
*/
static void app_enter_dlps_hook(void)
{
    gwin_low_pwr_enter();

#if MI_MCU_CMD_ENABLE
    rtk_mcu_perip_power_off();
#endif
}

/**
 * @brief this function will be called after exit DLPS
 *
 *  set PAD and wakeup pin config for enterring DLPS
 *
 * @param none
 * @return none
 * @retval void
*/
static void app_exit_dlps_hook(void)
{
    gwin_low_pwr_exit();

#if MI_MCU_CMD_ENABLE
    rtk_mcu_perip_power_on();
#endif
}

bool user_mode = true;
extern bool is_msc_power_on(void);
/**
 * @brief app_dlps_check_cb() contains the setting about app dlps callback.
*/
static bool app_dlps_check_cb(void)
{
    user_mode = gwin_low_pwr_check();

#if MI_MCU_CMD_ENABLE
    if(!rtk_mcu_is_idle())
        return false;
    else
#endif
    {
        return (!is_msc_power_on()) && user_mode;
    }	
}

#if MI_MANU_TEST_ENABLE
extern bool mi_mesh_otp_is_existed(void);
void app_mp_check(void)
{
    user_mode = mi_mesh_otp_is_existed();
    MI_LOG_ERROR("user mode: %d", user_mode);
}
#endif // MI_MANU_TEST_ENABLE
#endif // F_BT_DLPS_EN

static void pwr_mgr_init(void)
{
#if F_BT_DLPS_EN
    dlps_check_cb_reg(app_dlps_check_cb);
    DLPS_IORegUserDlpsEnterCb(app_enter_dlps_hook);
    DLPS_IORegUserDlpsExitCb(app_exit_dlps_hook);
    DLPS_IORegister();
    lps_mode_set(LPM_DLPS_MODE);
#if MI_MANU_TEST_ENABLE
    app_mp_check();
#endif
#endif
}

/**
 * @brief    Contains the initialization of all tasks
 * @note     There is only one task in BLE Peripheral APP, thus only one APP task is init here
 * @return   void
 */
static void task_init(void)
{
    gwin_protocol_task_init();
    gwin_main_task_init();
    app_task_init();
}


/**
 * @brief    Entry of APP code
 * @return   int (To avoid compile warning)
 */
int main(void)
{
    extern uint32_t random_seed_value;
    srand(random_seed_value);
    board_init();
    driver_init();
    le_gap_init(APP_MAX_LINKS);
    gap_lib_init();
    app_le_gap_init();
    app_le_profile_init();
    pwr_mgr_init();
    task_init();
    os_sched_start();

    return 0;
}
/** @} */ /* End of group PERIPH_DEMO_MAIN */


